/**
 * Objeto de juego.
 * @constructor
 * @param {Number} x - pos x.
 * @param {Number} y - pos y.
 * @param {Number} w - anchura (debe corresponder con anchura de sprite).
 * @param {Number} h - altura (debe corresponder con altura de sprite a usar).
 * @param {Number} rx - punto de registro de objeto x.
 * @param {Number} ry - punto de registro de objeto y.
 * @param {Number} sx - escala de objeto x (escala de objeto y de sprite a asociar).
 * @param {Number} sy - escala de objeto y (escala de objeto y de sprite a asociar).
 */
GameObject = function(x, y, w, h, rx, ry, sx, sy, speedX, speedY) {
    this.x = (x) ? x : 0;
    this.y = (y) ? y : 0;
    this.w = (w) ? w : 1;
    this.h = (h) ? h : 1;
    this.sx = (sx) ? sx : 1;
    this.sy = (sy) ? sy : 1;
    this.rx = (rx) ? rx : 0;
    this.ry = (ry) ? ry : 0;

    /*creo el rectangulo que representa a la entidad*/
    this.rectW = this.w * sx;
    this.rectH = this.h * sy;
    this.rect = new Rectangle(this.x, this.y, this.rectW, this.rectH, new Color(255, 255, 255, 0.5));
    this.rectRX = this.rx * this.sx;
    this.rectRY = this.ry * this.sy;

    this.controllers = [];
    this.updaters = [];

    this.speedX = speedX || 4;
    this.speedY = speedY || 4;

    
    this.vx=this.vy=0;
    this.velocity={
        x:this.vx,
        y:this.vy
    }
};


/**
 * Actualiza el estado de un objeto de juego.
 */
GameObject.prototype.update = function() {
    this.animation.x = this.x;
    this.animation.y = this.y;

    for (var i = 0; i < this.updaters.length; i++) {
        this.updaters[i].run();
    }
};
//update

GameObject.prototype.getVel = function(){
    return {
        x:this.vx,
        y:this.vy
    };
}//getVel


GameObject.prototype.getPos = function(){
    return {
        x:this.x,
        y:this.y
    };
}//getPos


GameObject.prototype.addUpdater = function(upd) {
    this.updaters.push(upd);
};

/**
 * Modifica la posicion de un objeto de juego.
 * @param {Number} x   posX.
 * @param {Number} y   posY.
 * @param {Boolean} rel true si se desea modificar la posicion de forma relativa, false en caso de modificarla de forma absoluta.
 */
GameObject.prototype.setPos = function(x, y, rel) {
    if (rel) {
        x = (x) ? x : 0;
        y = (y) ? y : 0;
        this.x += x;
        this.y += y;
    } else {
        x = (x == null || x == undefined) ? this.x : x;
        y = (y == null || y == undefined) ? this.y : y;
        this.x = x;
        this.y = y;
    }
};
//setPos

GameObject.prototype.move = function(dx, dy) {
    dx = (dx) ? dx : 0;
    dy = (dy) ? dy : 0;
    this.setPos(dx, dy, true);
};
//move

GameObject.prototype.addController = function(cont) {
    this.controllers.push(cont);
};

GameObject.prototype.control = function() {
    for (var i = 0; i < this.controllers.length; i++) {
        this.controllers[i].run();
    }
};

GameObject.prototype.debugDraw = function(){
    if (this.debugDrawOn && this.animation && this.animation.isVisible) {
        var rb = getBounds(this);
        var color=new Color(255, 255, 255, 0.5);
        var debugRect = new Rectangle(rb.x - rb.width / 2, rb.y - rb.height / 2, rb.width, rb.height, color);
        var ctx = $("canvas")[0].getContext("2d");
        debugRect.draw(ctx);
    }   
}

GameObject.prototype.tick = function() {
    this.control();

    this.update();

    this.debugDraw();
};
//tick

/**
 * Obtiene las dimensiones absolutas de un objeto de juego.
 * @return {Object} dimensiones absolutas anchura y altura dim = {"w":w , "h":h}.
 */
GameObject.prototype.getAbsDimensions = function() {
    var ww = this.w * this.sx;
    var hh = this.h * this.sy;
    var dim = {
        w: ww,
        h: hh
    };

    return dim;
};

GameObject.prototype.getRectBounds = function() {
    var absdim = this.getAbsDimensions();
    var rect = new Rectangle(this.x, this.y, absdim.w, absdim.h);
    return rect;
};


GameObject.prototype.calculateIntersection=function(go){
    return calculateGoogMathRectIntersection(this,go);
}